home *** CD-ROM | disk | FTP | other *** search
- /*******************************************
- *
- * special_opening(...
- *
- * Opening is erosion followed by dilation.
- * This routine will use the thinning
- * erosion routine. This will not allow
- * an object to erode to nothing.
- *
- * The number parameter specifies how
- * erosions to perform before doing one
- * dilation.
- *
- *******************************************/
-
- special_opening(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, threshold, number)
- char in_name[], out_name[];
- int il, ie, ll, le, number;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- threshold, value;
- {
- int a, b, count, i, j, k;
- int length, width;
- struct tiff_header_struct image_header;
-
- if(does_not_exist(out_name)){
- printf("\n\n output file does not exist %s", out_name);
- read_tiff_header(in_name, &image_header);
- round_off_image_size(&image_header,
- &length, &width);
- image_header.image_length = length*ROWS;
- image_header.image_width = width*COLS;
- create_allocate_tiff_file(out_name, &image_header,
- out_image);
- } /* ends if does_not_exist */
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- thinning(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, threshold, 1);
-
- if(number > 1){
- count = 1;
- while(count < number){
- count++;
- thinning(out_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, threshold, 1);
- } /* ends while */
- } /* ends if number > 1 */
-
- dilation(out_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, threshold);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends special_opening */
-
-
-
-
- /*******************************************
- *
- * thinning(...
- *
- * Use a variation of the grass fire
- * wave front approach.
- *
- * Raster scan the image left to right
- * and examine and thin the left edge pixels
- * (a 0 to value transition). Process them
- * normally and "save" the result. Next,
- * raster scan the image right to left and
- * save. Raster scan top to bottom and save.
- * Raster scan bottom to top and save.
- *
- * That is one complete pass.
- *
- * Keep track of pixels thinned for a
- * pass and quit when you make a complete
- * pass without thinning any pixels.
- *
- *******************************************/
-
- thinning(in_name, out_name, the_image, out_image,
- il, ie, ll, le, value, threshold, once_only)
- char in_name[], out_name[];
- int il, ie, ll, le, once_only;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- threshold, value;
- {
- int a, b, big_count, count, i, j, k,
- not_finished;
- int length, width;
- struct tiff_header_struct image_header;
-
- if(does_not_exist(out_name)){
- printf("\n\n output file does not exist %s", out_name);
- read_tiff_header(in_name, &image_header);
- round_off_image_size(&image_header,
- &length, &width);
- image_header.image_length = length*ROWS;
- image_header.image_width = width*COLS;
- create_allocate_tiff_file(out_name, &image_header,
- out_image);
- } /* ends if does_not_exist */
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- out_image[i][j] = the_image[i][j];
-
- not_finished = 1;
- while(not_finished){
-
- if(once_only == 1)
- not_finished = 0;
- big_count = 0;
-
- /***************************
- *
- * Scan left to right
- * Look for 0-value transition
- *
- ****************************/
-
- printf("\n");
- for(i=1; i<ROWS-1; i++){
- if( (i%10) == 0) printf("%3d", i);
- for(j=1; j<COLS-1; j++){
- if(the_image[i][j-1] == 0 &&
- the_image[i][j] == value){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b] == 0)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold){
- if(can_thin(the_image, i, j, value)){
- out_image[i][j] = 0;
- big_count++;
- } /* ends if can_thin */
- } /* ends if count > threshold */
- } /* ends if the_image == value */
- } /* ends loop over j */
- } /* ends loop over i */
-
- /**************************************
- *
- * Copy the output back to the input.
- *
- **************************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
-
- /***************************
- *
- * Scan right to left
- * Do this by scanning left
- * to right and look for
- * value-0 transition.
- *
- ****************************/
-
- printf("\n");
- for(i=1; i<ROWS-1; i++){
- if( (i%10) == 0) printf("%3d", i);
- for(j=1; j<COLS-1; j++){
- if(the_image[i][j+1] == 0 &&
- the_image[i][j] == value){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b] == 0)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold){
- if(can_thin(the_image, i, j, value)){
- out_image[i][j] = 0;
- big_count++;
- } /* ends if can_thin */
- } /* ends if count > threshold */
- } /* ends if the_image == value */
- } /* ends loop over j */
- } /* ends loop over i */
-
- /**************************************
- *
- * Copy the output back to the input.
- *
- **************************************/
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
-
- /***************************
- *
- * Scan top to bottom
- * Look for 0-value transition
- *
- ****************************/
-
- printf("\n");
- for(j=1; j<COLS-1; j++){
- if( (j%10) == 0) printf("%3d", j);
- for(i=1; i<ROWS-1; i++){
- if(the_image[i-1][j] == 0 &&
- the_image[i][j] == value){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b] == 0)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold){
- if(can_thin(the_image, i, j, value)){
- out_image[i][j] = 0;
- big_count++;
- } /* ends if can_thin */
- } /* ends if count > threshold */
- } /* ends if the_image == value */
- } /* ends loop over i */
- } /* ends loop over j */
-
- /**************************************
- *
- * Copy the output back to the input.
- *
- **************************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
-
- /***************************
- *
- * Scan bottom to top
- * Do this by scanning top
- * to bottom and look for
- * value-0 transition.
- *
- ****************************/
-
- printf("\n");
- for(j=1; j<COLS-1; j++){
- if( (j%10) == 0) printf("%3d", j);
- for(i=1; i<ROWS-1; i++){
- if(the_image[i+1][j] == 0 &&
- the_image[i][j] == value){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b] == 0)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold){
- if(can_thin(the_image, i, j, value)){
- out_image[i][j] = 0;
- big_count++;
- } /* ends if can_thin */
- } /* ends if count > threshold */
- } /* ends if the_image == value */
- } /* ends loop over i */
- } /* ends loop over j */
-
- /**************************************
- *
- * Copy the output back to the input.
- *
- **************************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
- /**************************************
- *
- * Now look at the result of this big
- * pass through the image.
- *
- ***************************************/
-
- printf("\n\nThinned %d pixels", big_count);
- if(big_count == 0)
- not_finished = 0;
- else{
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
- } /* ends else */
-
- } /* ends while not_finished */
-
- fix_edges(out_image, 3);
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
- } /* ends thinning */
-
-
-
-
-
- /*******************************************
- *
- * can_thin(...
- *
- * Look at the neighbors of the center pixel.
- * If a neighbor == value, then it must
- * have a neighbor == value other than the
- * center pixel.
- *
- * Procedure:
- * . Copy the 3x3 area surrounding pixel
- * i,j to a temp array.
- * . Set the center pixel to zero.
- * . Look at each non-zero pixel in temp.
- * . If you cannot find a non-zero
- * neighbor.
- * . Then you cannot thin.
- *
- *******************************************/
-
- can_thin(the_image, i, j, value)
- int i, j;
- short the_image[ROWS][COLS], value;
- {
- int a, b, c, d, count,
- no_neighbor, one=1, zero=0;
- short temp[3][3];
-
- /**************************************
- *
- * Copy the center pixel and its
- * neighbors to the temp array.
- *
- ***************************************/
-
- for(a=-1; a<2; a++)
- for(b=-1; b<2; b++)
- temp[a+1][b+1] = the_image[i+a][b+j];
-
- /**************************************
- *
- * Set the center of temp to 0.
- *
- ***************************************/
-
- temp[1][1] = 0;
-
- /**************************************
- *
- * Check the non-zero pixels in temp.
- *
- ***************************************/
-
- for(a=0; a<3; a++){
- for(b=0; b<3; b++){
- if(temp[a][b] == value){
- temp[a][b] = 0;
-
- /**************************************
- *
- * Check the neighbors of this pixel
- * If there is a single non-zero
- * neighbor, set no_neighbor = 0.
- *
- ***************************************/
-
- no_neighbor = 1;
- for(c=-1; c<2; c++){
- for(d=-1; d<2; d++){
- if( ((a+c) >= 0) &&
- ((a+c) <= 2) &&
- ((b+d) >= 0) &&
- ((b+d) <= 2)){
- if(temp[a+c][b+d] == value){
- no_neighbor = 0;
- } /* ends if temp == value */
- } /* ends if part of temp array */
- } /* ends loop over d */
- } /* ends loop over c */
- temp[a][b] = value;
-
- /**************************************
- *
- * If the non-zero pixel did not
- * have any non-zero neighbors,
- * no_neighbor still equals 1,
- * and we cannot thin, so return
- * zero.
- *
- ***************************************/
-
- if(no_neighbor){
- return(zero);
- }
- } /* ends if temp[a][b] == value */
- } /* ends loop over b */
- } /* ends loop over a */
-
- return(one);
-
- } /* ends can_thin */
-
-
-
-
-
- /*******************************************
- *
- * special_closing(...
- *
- * Closing is dilation followed by erosion.
- * This routine will use the dilate_not_join
- * dilation routine. This will not allow
- * two separate objects to join.
- *
- * The number parameter specifies how
- * dilations to perform before doing one
- * erosion.
- *
- *******************************************/
-
- special_closing(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, threshold, number)
- char in_name[], out_name[];
- int il, ie, ll, le, number;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- threshold, value;
- {
- int a, b, count, i, j, k;
- int length, width;
- struct tiff_header_struct image_header;
-
- if(does_not_exist(out_name)){
- printf("\n\n output file does not exist %s", out_name);
- read_tiff_header(in_name, &image_header);
- round_off_image_size(&image_header,
- &length, &width);
- image_header.image_length = length*ROWS;
- image_header.image_width = width*COLS;
- create_allocate_tiff_file(out_name, &image_header,
- out_image);
- } /* ends if does_not_exist */
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- dilate_not_join(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, threshold);
-
- if(number > 1){
- count = 1;
- while(count < number){
- count++;
- dilate_not_join(out_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, threshold);
- } /* ends while */
- } /* ends if number > 1 */
-
- erosion(out_name, out_name, the_image,
- out_image, il, ie, ll, le,
- value, threshold);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends special_closing */
-
-
-
-
- /*******************************************
- *
- * dilate_not_join(...
- *
- * Use a variation of the grass fire
- * wave front approach.
- *
- * Raster scan the image left to right
- * and examine and dilate the left edge pixels
- * (a value to 0 transition). Process them
- * normally and "save" the result. Next,
- * raster scan the image right to left and
- * save. Raster scan top to bottom and save.
- * Raster scan bottom to top and save.
- *
- * That is one complete pass.
- *
- *******************************************/
-
- dilate_not_join(in_name, out_name, the_image, out_image,
- il, ie, ll, le, value, threshold)
- char in_name[], out_name[];
- int il, ie, ll, le;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- threshold, value;
- {
- int a, b, count, i, j, k;
- int length, width;
- struct tiff_header_struct image_header;
-
- if(does_not_exist(out_name)){
- printf("\n\n output file does not exist %s", out_name);
- read_tiff_header(in_name, &image_header);
- round_off_image_size(&image_header,
- &length, &width);
- image_header.image_length = length*ROWS;
- image_header.image_width = width*COLS;
- create_allocate_tiff_file(out_name, &image_header,
- out_image);
- } /* ends if does_not_exist */
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- out_image[i][j] = the_image[i][j];
-
- /***************************
- *
- * Scan left to right
- * Look for value-0 transition
- *
- ****************************/
-
- printf("\n");
- for(i=1; i<ROWS-1; i++){
- if( (i%10) == 0) printf("%3d", i);
- for(j=1; j<COLS-1; j++){
- if(the_image[i][j-1] == value &&
- the_image[i][j] == 0){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b]==value)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold){
- if(can_dilate(the_image,i,j,value)){
- out_image[i][j] = value;
- } /* ends if can_dilate */
- } /* ends if count > threshold */
- } /* ends if the_image == value */
- } /* ends loop over j */
- } /* ends loop over i */
-
- /**************************************
- *
- * Copy the output back to the input.
- *
- **************************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
- /***************************
- *
- * Scan right to left
- * Do this by scanning left
- * to right and look for
- * 0-value transition.
- *
- ****************************/
-
- printf("\n");
- for(i=1; i<ROWS-1; i++){
- if( (i%10) == 0) printf("%3d", i);
- for(j=1; j<COLS-1; j++){
- if(the_image[i][j+1] == value &&
- the_image[i][j] == 0){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b]==value)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold){
- if(can_dilate(the_image,i,j,value)){
- out_image[i][j] = value;
- } /* ends if can_dilate */
- } /* ends if count > threshold */
- } /* ends if the_image == value */
- } /* ends loop over j */
- } /* ends loop over i */
-
- /**************************************
- *
- * Copy the output back to the input.
- *
- **************************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
-
- /***************************
- *
- * Scan top to bottom
- * Look for value-0 transition
- *
- ****************************/
-
- printf("\n");
- for(j=1; j<COLS-1; j++){
- if( (j%10) == 0) printf("%3d", j);
- for(i=1; i<ROWS-1; i++){
- if(the_image[i-1][j] == value &&
- the_image[i][j] == 0){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b]==value)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold){
- if(can_dilate(the_image,i,j,value)){
- out_image[i][j] = value;
- } /* ends if can_dilate */
- } /* ends if count > threshold */
- } /* ends if the_image == value */
- } /* ends loop over i */
- } /* ends loop over j */
-
- /**************************************
- *
- * Copy the output back to the input.
- *
- **************************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
-
-
- /***************************
- *
- * Scan bottom to top
- * Do this by scanning top
- * to bottom and look for
- * 0-value transition.
- *
- ****************************/
-
- printf("\n");
- for(j=1; j<COLS-1; j++){
- if( (j%10) == 0) printf("%3d", j);
- for(i=1; i<ROWS-1; i++){
- if(the_image[i+1][j] == value &&
- the_image[i][j] == 0){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b]==value)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold){
- if(can_dilate(the_image,i,j,value)){
- out_image[i][j] = value;
- } /* ends if can_dilate */
- } /* ends if count > threshold */
- } /* ends if the_image == value */
- } /* ends loop over i */
- } /* ends loop over j */
-
- /**************************************
- *
- * Copy the output back to the input.
- *
- **************************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
-
- fix_edges(out_image, 3);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends dilate_not_join */
-
-
-
-
-
- /*******************************************
- *
- * can_dilate(...
- *
- * This function decides if you can dilate
- * (set to value) a pixel without joining
- * two separate objects in a 3x3 area.
- *
- * First, you grow regions inside the 3x3
- * area. Next, check if the center pixel
- * has neighbors with differing values.
- * If it does, you cannot dilate it because
- * that would join two separate objects.
- *
- *******************************************/
-
- can_dilate(the_image, i, j, value)
- int i, j;
- short the_image[ROWS][COLS], value;
- {
- int a, b, c, d, count, found=0,
- no_neighbor,
- stack_pointer=-1,
- stack_empty=1,
- stack[12][2],
- pop_a, pop_b,
- one=1,
- zero=0;
- short first_value, label = 2, temp[3][3];
-
- /**************************************
- *
- * Copy the center pixel and its
- * neighbors to the temp array.
- *
- ***************************************/
-
- for(a=-1; a<2; a++)
- for(b=-1; b<2; b++)
- temp[a+1][b+1] = the_image[i+a][b+j];
-
- /**************************************
- *
- * Grow objects inside the temp array.
- *
- ***************************************/
-
- for(a=0; a<3; a++){
- for(b=0; b<3; b++){
- stack_empty = 1;
- stack_pointer = -1;
- if(temp[a][b] == value){
- little_label_and_check(temp, stack, label,
- &stack_empty,
- &stack_pointer,
- a, b, value);
- found = 1;
- } /* ends if temp == value */
-
- while(stack_empty == 0){
- pop_a = stack[stack_pointer][0]; /* POP */
- pop_b = stack[stack_pointer][1]; /* POP */
- --stack_pointer;
- if(stack_pointer <= 0){
- stack_pointer = 0;
- stack_empty = 1;
- } /* ends if stack_pointer */
- little_label_and_check(temp, stack, label,
- &stack_empty,
- &stack_pointer,
- pop_a, pop_b, value);
- } /* ends while stack_empty == 0 */
-
- if(found){
- found = 0;
- label++;
- } /* ends if object_found */
- } /* ends loop over b */
- } /* ends loop over a */
-
- /**************************************
- *
- * Look at the center pixel. If it
- * has two non-zero neigbors whose
- * pixels are not the same, then
- * you cannot dilate.
- *
- ***************************************/
-
- first_value = -1;
- for(a=0; a<3; a++){
- for(b=0; b<3; b++){
- if(temp[a][b] != 0 &&
- first_value == -1){
- first_value = temp[a][b];
- }
- if(temp[a][b] != 0 &&
- first_value != -1){
- if(temp[a][b] != first_value){
- return(zero);
- }
- }
- } /* ends loop over b */
- } /* ends loop over a */
-
- return(one);
-
- } /* ends can_dilate */
-
-
-
-
- /*******************************************
- *
- * little_label_and_check(...
- *
- * This function labels the objects in
- * in a 3x3 area.
- *
- *******************************************/
-
- little_label_and_check(temp, stack, label, stack_empty,
- stack_pointer, a, b, value)
- int a, b, stack[12][2],
- *stack_empty, *stack_pointer;
- short temp[3][3], label, value;
- {
- int c, d;
-
- temp[a][b] = label;
- for(c=a-1; c<=a+1; c++){
- for(d=b-1; d<=b+1; d++){
- if(c >= 0 &&
- c <= 2 &&
- d >= 0 &&
- d <= 2)
- if(temp[c][d] == value){ /* PUSH */
- *stack_pointer = *stack_pointer + 1;
- stack[*stack_pointer][0] = c;
- stack[*stack_pointer][1] = d;
- *stack_empty = 0;
- } /* ends if temp == value */
- } /* ends loop over d */
- } /* ends loop over c */
-
- } /* ends little_label_and_check */
-
-
-